home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / sozobon2.zoo / ld / ld.c next >
C/C++ Source or Header  |  1990-12-13  |  6KB  |  312 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  */
  11.  
  12. static    char    Version[] =
  13. "ld Version 1.01  Copyright (c) 1988 by Sozobon, Limited.";
  14.  
  15. #include <stdio.h>
  16. #include "ld.h"
  17.  
  18. int mflag, vflag, bflag;
  19. int symout = 0;
  20. int multipass = 0;
  21.  
  22. char *oname = NULL;
  23.  
  24. main(argc, argv)
  25. char **argv;
  26. {
  27.     int i, j, k;
  28.     struct oinfo *op;
  29.     struct sinfo *sp;
  30.  
  31.     for (i=1; i<argc; i++) {
  32.         if (argv[i][0] == '-') {
  33.             if (doopt(&argv[i][1], argv[i+1]))
  34.                 i++;
  35.         } else
  36.             pass0(argv[i]);
  37.     }
  38.  
  39.     if (nfiles < 1)
  40.         exit(0);
  41.     /*
  42.      * If no output name was given, form it based on the name
  43.      * of the first file name on the command line.
  44.      */
  45.     if (oname == NULL) {        /* no name assigned */
  46.         char    *p, *strchr(), *strrchr(), *myalloc();
  47.  
  48.         if ((p = strrchr(files[0].fname, '\\')) != NULL)
  49.             p++;
  50.         else
  51.             p = files[0].fname;
  52.  
  53.         oname = myalloc(14L);        /* max. file name size */
  54.  
  55.         strcpy(oname, p);        /* copy the base name */
  56.  
  57.         /*
  58.          * Truncate any existing suffix and add our own.
  59.          */
  60.         if ((p = strchr(oname, '.')) != NULL)
  61.             *p = '\0';
  62.  
  63.         strcat(oname, ".ttp");
  64.     }
  65.  
  66.     for (i=0; i<nfiles; i++)
  67.         pass1(i);
  68.  
  69.     obj_rel();
  70.     sym_chk();
  71.  
  72.     if (mflag)
  73.     for (i=0; i<nobj; i++) {
  74.         op = &obj[i];
  75.         onm_pr(i, stdout);
  76.         if (op->oh.tsize)
  77.         printf("\tT %lx @%lx", op->oh.tsize, op->tbase);
  78.         if (op->oh.dsize)
  79.         printf("\tD %lx @%lx", op->oh.dsize, op->dbase);
  80.         if (op->oh.bsize)
  81.         printf("\tB %lx @%lx", op->oh.bsize, op->bbase);
  82.         putchar('\n');
  83.     }
  84.  
  85.     pass2();
  86.  
  87.     exit(0);
  88. }
  89.  
  90. onm_pr(i, fd)
  91. FILE *fd;
  92. {
  93.     struct oinfo *op;
  94.     struct finfo *fp;
  95.  
  96.     if (i < 0) {
  97.         fprintf(fd, "CMD LINE");
  98.         return;
  99.     }
  100.     op = &obj[i];
  101.     fp = &files[op->fno];
  102.     fprintf(fd, "%.8s", fp->fname);
  103.     if (op->aname[0])
  104.         fprintf(fd, "(%.14s)", op->aname);
  105. }
  106.  
  107. doopt(s, s2)
  108. char *s, *s2;
  109. {
  110.     char *myalloc();
  111.  
  112.     while (*s) {
  113.         switch (*s) {
  114.         case 'm':    /* print load map */
  115.             mflag++;    break;
  116.         case 'V':
  117.             fprintf(stderr, "%s\n", Version);
  118.             break;
  119.         case 'v':    /* verbose */
  120.             vflag++;    break;
  121.         case 't':    /* put symbol table in obj */
  122.             symout = 1;    break;
  123.         case 'b':    /* big, so dont pre-read td & rel */
  124.             bflag++;
  125.             if (lbuf == NULL) {
  126.                 lbuf = (short *)myalloc(
  127.                     (long)(LBUFCNT+1) *
  128.                     sizeof(short));
  129.                 rbuf = (short *)myalloc(
  130.                     (long)(LBUFCNT+1) *
  131.                     sizeof(short));
  132.             }
  133.             break;
  134.         case 'p':    /* go through libs multi times */
  135.             multipass = 1;
  136.             if (skip == NULL)
  137.                 skip = (struct skipstr *)myalloc(
  138.                         (long)MAXLIB *
  139.                         sizeof(*skip));
  140.             break;
  141.         case 'f':    /* file of objects */
  142.             fpass1(s2);
  143.             return 1;
  144.         case 'o':    /* object file name */
  145.             oname = s2;
  146.             return 1;
  147.         case 'u':    /* undefine name */
  148.             undef(s2);
  149.             return 1;
  150.         }
  151.         s++;
  152.     }
  153.     return 0;
  154. }
  155.  
  156. char *
  157. savestr(s)
  158. char *s;
  159. {
  160.     int i;
  161.     char *rets, *myalloc();
  162.  
  163.     i = strlen(s);
  164.     rets = myalloc((long)i+1);
  165.     strcpy(rets, s);
  166.     return rets;
  167. }
  168.  
  169. char *
  170. myalloc(n)
  171. long n;
  172. {
  173.     char *retv, *malloc();
  174.  
  175.     if (n > 64000L) {
  176.         fprintf(stderr, "Chunk too big %ld\n", n);
  177.         exit(1);
  178.     }
  179.     retv = malloc((unsigned)n);
  180.     if (retv == NULL) {
  181.         fprintf(stderr, "Malloc failure\n");
  182.         exit(1);
  183.     }
  184.     return retv;
  185. }
  186.  
  187. struct sinfo *
  188. hashlst(s)
  189. char *s;
  190. {
  191.     return hashs[hfun(s)];
  192. }
  193.  
  194. hashins(sp)
  195. struct sinfo *sp;
  196. {
  197.     register i;
  198.  
  199.     i = hfun(sp->sy.name);
  200.     sp->hchain = hashs[i];
  201.     hashs[i] = sp;
  202. }
  203.  
  204. hfun(s)
  205. register char *s;
  206. {
  207.     register char i;
  208.  
  209.     i = *s;
  210.     i += *++s;
  211.     i += *++s;
  212.     i += *++s;
  213.     return i & HMASK;
  214. }
  215.  
  216. myncmp(p, q)
  217. register long *p, *q;
  218. {
  219.     if (p[0] == q[0] && p[1] == q[1])
  220.         return 0;
  221.     return 1;
  222. }
  223.  
  224. struct sinfo *
  225. lookup(s)
  226. char *s;
  227. {
  228.     register struct sinfo *sp;
  229.  
  230.     for (sp = hashlst(s); sp; sp = sp->hchain)
  231.         if (myncmp(s, sp->sy.name) == 0)
  232.             return sp;
  233.  
  234.     return NULL;
  235. }
  236.  
  237. obj_rel()
  238. {
  239.     register i;
  240.     register struct oinfo *p;
  241.  
  242.     p = obj;
  243.     for (i=0; i<nobj; i++) {
  244.         p->dbase += textsize;
  245.         p->bbase += textsize+datasize;
  246.         p++;
  247.     }
  248. }
  249.  
  250. sym_chk()
  251. {
  252.     register i, fl;
  253.     register struct sinfo *sp;
  254.     register struct oinfo *p;
  255.     long offs, base;
  256.  
  257.     base = textsize+datasize+bsssize;
  258.     sp = sym;
  259.     for (i=0; i<nsym; i++) {
  260.         fl = sp->sy.flags & 0xff;
  261.         if (fl == 0x88) {
  262.             fprintf(stderr, "Undef %.8s from ", sp->sy.name);
  263.             onm_pr(sp->onum, stderr);
  264.             fputc('\n', stderr);
  265.         }
  266.         else if (fl == 0xa8) {
  267.             offs = sp->sy.value;
  268.             sp->sy.value = base;
  269.             sp->sy.flags = 0xa1;
  270.             base += offs;
  271.         } else {
  272.             p = &obj[sp->onum];
  273.             switch (fl & 7) {
  274.             case 1:
  275.                 offs = p->bbase;    break;
  276.             case 2:
  277.                 offs = p->tbase;    break;
  278.             case 4:
  279.                 offs = p->dbase;    break;
  280.             default:
  281.                 offs = 0;
  282.             }
  283.             sp->sy.value += offs;
  284.         }
  285.         sp++;
  286.     }
  287.     comsize = base - (textsize+datasize+bsssize);
  288. }
  289.  
  290. int symnum;
  291. struct sym *symptr;
  292.  
  293. symabs(iptr)
  294. char *iptr;
  295. {
  296.     symptr = (struct sym *)iptr;
  297.     symnum = 0;
  298. }
  299.  
  300. symread(sp)
  301. struct sym *sp;
  302. {
  303.     int i, fl;
  304.  
  305.     *sp = symptr[symnum++];
  306.  
  307.     fl = sp->flags & 0xff;
  308.     if (fl == 0xa8 && sp->value == 0)
  309.         sp->flags = 0x88;
  310.     return 1;
  311. }
  312.